Schema (effect)
Decoding
外部からの入力(JSONなど)を TypeScript の型に変換
Encoding
TypeScript の値を外部形式(例:文字列)に変換
Asserting
値が指定されたスキーマに準拠しているかチェック
Schema生成
JSON Schema を自動で生成
Pretty Printing
データの見やすい表示
Arbitrary生成
Schema<Type, Encoded, Requirements>
Type
出力
decode 後の型
Encoded
入力
encode 前の型
Requirements
code:_
┌─────────┐ ┌───┐ ┌───┐ ┌─────────┐
| unknown | | A | | I | | unknown |
└─────────┘ └───┘ └───┘ └─────────┘
| | | |
| validate | | |
|─────────────►│ | |
| | | |
| is | | |
|─────────────►│ | |
| | | |
| asserts | | |
|─────────────►│ | |
| | | |
| encodeUnknown| | |
|─────────────────────────►| |
| | |
| encode | |
|──────────►│ |
| | |
| decode | |
| ◄─────────| |
| | |
| | decodeUnknown|
| ◄────────────────────────|
code:ts
import { Schema } from "effect"
// 定義
const Person = Schema.Struct({
name: Schema.String,
age: Schema.Number
})
型の取得
3種類の方法がある
code:ts
type Person1 = typeof Person.Type
type Person2 = Schema.Schema.Type<typeof Person>
interface Person3 extends Schema.Schema.Type<typeof Person> {}
1でええやんmrsekut.icon
何のために2番目あるんや
3番目は読みやすさとパフォーマンスが良いと書いているが、どこが読みやすいのかわからん
入力の型も得られる
.Encoded
code:ts
type Person_ = typeof Person.Encoded
Contextの型
code:ts
type PersonContext = typeof Person.Context
型の内部構造を隠蔽した型
code:ts
const _Person = Schema.Struct({
name: Schema.String,
age: Schema.Number
})
// Declare the type interface to make it opaque
interface Person extends Schema.Schema.Type<typeof _Person> {}
// Re-declare the schema as opaque
const Person: Schema.Schema<Person> = _Person
decode
失敗したらthrow error
code:ts
Schema.decodeUnknownSync(Person)(input)
カリー化されてるんやmrsekut.icon
Option型を返す
Either型を返す
decodeしてPromiseを返す
なぜ?mrsekut.icon
code:ts
const asyncSchema = Schema.transformOrFail(PersonId, Person, {
strict: true,
// Decode with simulated async transformation
decode: (id) =>
Effect.succeed({ id, name: "name", age: 18 }).pipe(
Effect.delay("10 millis")
),
encode: (person) =>
Effect.succeed(person.id).pipe(Effect.delay("10 millis"))
})
Effect.runPromise(Schema.decodeUnknown(asyncSchema)(1)).then(console.log)
非同期な変換が含まれるSchemaというのがあるらしい
decodeしてEffectを返す
exact
デフォルト
code:ts
import { Schema } from "effect"
const schema = Schema.Struct({ a: Schema.Unknown })
const input = {}
console.log(Schema.decodeUnknownSync(schema)(input))
// Output: { a: undefined }
exact: true
code:ts
import { Schema } from "effect"
const schema = Schema.Struct({ a: Schema.Unknown })
const input = {}
console.log(Schema.decodeUnknownSync(schema)(input, { exact: true }))
/*
throws
ParseError: { readonly a: unknown }
└─ is missing
*/
まあ、decode時のみの挙動なら許容かmrsekut.icon
encoding
失敗したらthrow error
Option型を返す
Either型を返す
encodeしてPromise返す
encodeしてEffect返す
eoncdeがサポートされていないschemaもある
値にあって、Schemaにないpropertyは削除される
onExcessPropertyを使えば残すこともできる
encode時のエラーの取得
propertyの順序を固定できる
いつ使う年mrsekut.icon
使い所がわからん
code:ts
const mySymbol = Symbol.for("mySymbol")
const schema = Schema.UniqueSymbolFromSelf(mySymbol)
.pick
.omit
.partial
.required
変換処理などを取り除いて、SchemaのTypeだけ取り出す
encode形式だけ取り出す
変換前の制約だけ残す
e.g.
code:ts
const Original = Schema.Struct({
foo: Schema.String.pipe(
Schema.minLength(3),
Schema.compose(Schema.Trim)
)
})
decode時に前後の空白を取り除く
任意の型(この例では File)に対してスキーマを定義できる
code:ts
const FileFromSelf = Schema.declare(
(input: unknown): input is File => input instanceof File
)
declare の第一引数は 型ガード関数。
decodeUnknownSync を使うことで、そのスキーマに対して バリデーション + デコード ができます。
型コンストラクタ
genericなSchemaも定義できる
QuickCheck風のランダムデータ生成(Arbitrary)には、追加のアノテーションが必要です:
code:ts
arbitrary: () => (fc) =>
これにより FastCheck.sample を使ってテスト用のデータを生成できます。
「外部のデータ構造」から「内部の型」への変換ルールを表現するもの
code:ts
import { Schema } from "effect"
const Person = Schema.Struct({
name: Schema.String,
age: Schema.propertySignature(Schema.NumberFromString).annotations({
title: "Age" // Annotation to label the age field
})
})
これは "age" フィールドが string(例: "18")として与えられても、内部的には number として扱えるようにするスキーマを定義しています。
🔍 PropertySignature の型パラメータ
code:_
PropertySignature<ToToken, ToType, FromKey, FromToken, FromType, HasDefault, Context>
それぞれの意味は:
table:_
パラメータ 意味
ToToken 内部型(出力)での : or ?:(必須かオプショナルか)
ToType 出力時の型(例: number)
FromKey 入力側のフィールド名。省略時はToと同じ
FromToken 入力側の : or ?:(必須かオプショナルか)
FromType 入力時の型(例: string)
HasDefault デフォルト値があるか(true or false)
Context 注釈やメタ情報など(通常 never)
例:
code:ts
age: PropertySignature<":", number, never, ":", string, false, never>
これは次のように読み取れます:
age フィールドは必須(:)
出力は number
入力も必須(:)
入力は string
デフォルト値なし
🔁 フィールド名のマッピング(fromKey)
外部データのキー名が異なる場合には、Schema.fromKey を使います。
code:ts
const Person = Schema.Struct({
age: Schema.propertySignature(Schema.NumberFromString).pipe(
Schema.fromKey("AGE")
)
})
この例では "AGE" というキーを内部の age にマッピングしています。
schema
Introduction
Getting Started
Basic Usage
Filters
Advanced Usage
Projections
Transformations
Annotations
説明つけるやつ
Error Messages
Error Formatters
エラーを見やすっく
Class APIs
Default Constructors
Effect Data Types
クソ長い
Overview
Interop With Data
Config
Option
OptionFromSelf
OptionFromUndefinedOr
OptionFromNullOr
OptionFromNullishOr
OptionFromNonEmptyTrimmedString
Either
EitherFromSelf
EitherFromUnion
Exit
Exit
Handling Defects in Serialization
ExitFromSelf
ReadonlySet
ReadonlySet
ReadonlySetFromSelf
HashSet
HashSetFromSelf
SortedSet
SortedSet
SortedSetFromSelf
Duration
Duration
DurationFromSelf
DurationFromMillis
DurationFromNanos
clampDuration
Redacted
Redacted
RedactedFromSelf
Standard Schema
JSON Schema
Equivalence
Pretty Printer